/**
 * Copyright 2014 opencxa.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.cxa.rpc.cloud.configurationConsole.userManagement;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JOptionPane;
import javax.swing.table.AbstractTableModel;

import org.cxa.misc.ClassUtils;
import org.cxa.rpc.cloud.client.TransientDevice;
import org.cxa.rpc.cloud.server.components.authentication.Group;
import org.cxa.rpc.messages.ResponseRpcMessage;


/**
 * @author Christopher Armenio
 *
 */
public class GroupTableModel extends AbstractTableModel
{
	private static final long serialVersionUID = -5343867294295954254L;
	
	@SuppressWarnings("serial")
	private static final LinkedHashMap<String, Class<?>> COLS = new LinkedHashMap<String, Class<?>>()
	{{
		put("ID", Integer.class);
		put("Name", String.class);
	}};
	
	
	private final TransientDevice tDev;
	private final List<Group> localGroupList = new ArrayList<Group>();
	
	
	public GroupTableModel(TransientDevice tDevIn)
	{
		this.tDev = tDevIn;
	}
	
	
	public boolean refreshFromServer()
	{
		ResponseRpcMessage resp = this.tDev.sendRequest("/sys/auth", "getGroupList");
		if( !resp.getWasSuccessful() ) return false;
		
		this.localGroupList.clear();
		List<?> groups_raw = (List<?>)resp.getReturnValue(List.class);
		for( Object currGroup_raw : groups_raw ) 
		{
			Group currGroup = (Group)ClassUtils.classFromPojoMap(currGroup_raw, Group.class);
			if( currGroup == null ) continue;
			this.localGroupList.add(currGroup);
		}
		this.fireTableDataChanged();
		
		return true;
	}
	
	
	public Group getGroupAtRow(int rowIndexIn)
	{
		return this.localGroupList.get(rowIndexIn);
	}
	
	
	public void deleteGroupById(Integer idIn)
	{
		// first, make sure _we_ know about this group
		Group targetGroup = null;
		for( Group currGroup : this.localGroupList )
		{
			if( currGroup.getId() == idIn )
			{
				targetGroup = currGroup;
				break;
			}
		}
		if( targetGroup == null ) return;
	
		// if we made it here, we found the group...delete it on the server
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("id", idIn);
		ResponseRpcMessage resp = this.tDev.sendRequest("/sys/auth", "deleteGroupById", params);
		if( !resp.getWasSuccessful() )
		{
			JOptionPane.showMessageDialog(null, String.format("Error deleting group:\n%s", resp.getException().getFormattedErrorString()));
			return;
		}
		
		// if we made it here, we deleted it on the server, now delete it locally
		this.localGroupList.remove(targetGroup);
		this.fireTableDataChanged();
	}
	
	
	@Override
	public String getColumnName(int colIndexIn)
	{
		int currIndex = 0;
		Iterator<String> it = COLS.keySet().iterator();
		while( it.hasNext() )
		{
			String currVal = it.next();
			if( currIndex++ == colIndexIn ) return currVal;
		}
		return null;
	}
	
	
	@Override
	public int getRowCount()
	{
		return this.localGroupList.size(); 
	}
	

	@Override
	public int getColumnCount()
	{
		return COLS.size();
	}

	
	@Override
	public Object getValueAt(int rowIndexIn, int colIndexIn)
	{
		Group selectedGroup = this.localGroupList.get(rowIndexIn);
		if( selectedGroup == null ) return null;
		
		Object retVal = null;
		switch( colIndexIn )
		{
			case 0:
				retVal = selectedGroup.getId();
				break;
				
			case 1:
				retVal = selectedGroup.getName();
				break;
		}
		return retVal;
	}
	
	
	@Override
	public Class<?> getColumnClass(int colIndexIn)
	{
		int currIndex = 0;
		Iterator<Class<?>> it = COLS.values().iterator();
		while( it.hasNext() )
		{
			Class<?> currType = it.next();
			if( currIndex++ == colIndexIn ) return currType;
		}
		return null;
	}
}
